/* @flow */

import { ASSET_TYPES } from "shared/constants";
import { isPlainObject, validateComponentName } from "../util/index";

export function initAssetRegisters(Vue: GlobalAPI) {
  /**
   * Create asset registration methods.
   * 定义ASSET_TYPES中每个属性方法，其中包括component directive filter
   */
  ASSET_TYPES.forEach((type) => {
    Vue[type] = function (
      id: string,
      definition: Function | Object
    ): Function | Object | void {
      if (!definition) {
        //直接返回注册组件的构造函数
        return this.options[type + "s"][id];
      } else {
        /* istanbul ignore if */
        //如果是开发环境并且type是component则进行组件名字验证
        if (process.env.NODE_ENV !== "production" && type === "component") {
          validateComponentName(id);
        }
        //如果type是component并且definition传的是一个对象
        if (type === "component" && isPlainObject(definition)) {
          //如果definition没有name属性，则把id赋值给definition的name
          definition.name = definition.name || id;
          // Vue.extend() 创建子组件，返回子类构造器
          definition = this.options._base.extend(definition);
        }
        if (type === "directive" && typeof definition === "function") {
          definition = { bind: definition, update: definition };
        }
        // 为Vue.options 上的component属性添加将子类构造器
        this.options[type + "s"][id] = definition;
        return definition;
      }
    };
  });
}
